/*
 * Copyright � 2008 Nokia Corporation.
 */

#ifndef SUDOKUGAMELOGIC_H
#define SUDOKUGAMELOGIC_H

// INCLUDES
#include <e32std.h>
#include <e32base.h>
#include <f32file.h>

// CLASS DECLARATION

const TInt READ_BUFFER_SIZE = 20;
const TInt SUDOKU_GRID_SIZE = 9;
const TInt SUDOKU_AREA_SIZE = 3;

/***
 * TGridItem class
 */
class TGridItem
    {
    public:
        TInt    iValue;
        TInt    iRow;
        TInt    iCol;
        TInt    iArea;
        TUint   iShowConflict;
        TUint   iLocked;
        TRect   iRect;
    };

/***
 * CGrid class
 */
class CGrid : public CBase
    {
    public:
        ~CGrid ( );
        static CGrid* NewL ( );
        static CGrid* NewLC ( );

    public:
        TBool SetValue(TGridItem& aItem, TInt aValue, TBool& aConflict);
        void AddItem(TGridItem& aNewItem);
        TInt GetItem(TPoint& aPosition, TGridItem*& aItem);
        void SetItemRects(TRect& aTl);
        RArray<TGridItem>* Items();
        void CleanItemValue(TInt aIndex);
        void CleanConflicts();
        
    private:
        CGrid ( );
        void ConstructL ( );

    
    private:
        RArray<TGridItem>               iGridItems;
    };

/***
 * CSudokuGameLogic class
 */
class CSudokuGameLogic : public CBase
    {
    public:
        ~CSudokuGameLogic ( );
        static CSudokuGameLogic* NewL ( );
        static CSudokuGameLogic* NewLC ( );
    
    public:
        void NewGameL();
        void SetValue(TPoint& aPosition, TInt aValue);
        TInt RandInt(const TInt aLow, const TInt aHigh);
        void SetBoardItemRects(TRect aBoardRect);
        RArray<TGridItem>* GridItems();
        TGridItem* GetActiveItem(TPoint aPoint);
        void CleanConflicts();
        void RestartGame();
        inline TInt MovesCount(){return iMoves;};
        inline TInt EmptyCount(){return iEmpty;};
        inline TBool IsConflict(){return iConfictValues;};
        inline void ResetConflict(){iConfictValues=EFalse;};
        
    private:
        CSudokuGameLogic ( );
        void ConstructL ( );
        void LoadBoardL();
        void CreateBoardL();
        void RandomRemove();
        void CalculateEmptyCount();
        
    private:
        CGrid*                          iSudokuGrid;
        RFs                             iRfs;
        RFile                           iFile;
        TTime                           iTime;
        TInt64                          iRandSeed;
        HBufC16*                        iSudokuData;
        TBuf8<READ_BUFFER_SIZE>         iReadBuffer8;
        TInt                            iMoves;
        TInt                            iEmpty;
        TBool                           iConfictValues;
    };

#endif // SUDOKUGAMELOGIC_H
